package org.javaboy.demo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 这里相当于生成了一个动态代理对象
 *
 * public class ProxyCalculator implements ICalculator{
 *     ICalculatorImpl calculatorImpl = new ICalculatorImpl();
 *     public int add(int a,int b){
 *         long startTime = System.currentTimeMillis();
 *         int result = calculatorImpl.add(a,b);
 *         long endTime = System.currentTimeMillis();
 *         System.out.println(method.getName() + " 方法执行耗时 " + (endTime - startTime) + " 毫秒");
 *         return result;
 *     }
 * }
 */
public class Demo {
    public static void main(String[] args) {
        ICalculatorImpl calculatorImpl = new ICalculatorImpl();
        //这个就是生成一个代理对象（动态代理）
        //1. 类加载器
        //2. 要生成的代理对象它需要实现的接口
        //3. 这个参数是真正的动态代理的生成逻辑
        //这个方法的返回值就是一个代理对象，第二个参数就表示这个返回的对象所需要实现的接口
        ICalculator proxObj = (ICalculator) Proxy.newProxyInstance(Demo.class.getClassLoader(), new Class[]{ICalculator.class}, new InvocationHandler() {
            /**
             *
             * @param proxy 这就是生成的代理对象
             * @param method 这个就是被代理的方法
             * @param args 这个是方法的参数，用户调用方法的时候传入的参数
             * @return 这个就是代理方法的返回值
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                long startTime = System.currentTimeMillis();
                //这个地方相当于触发了 add 方法的执行
                Object invoke = method.invoke(calculatorImpl, args);
                long endTime = System.currentTimeMillis();
                System.out.println(method.getName() + " 方法执行耗时 " + (endTime - startTime) + " 毫秒");
                return invoke;
            }
        });
        int add = proxObj.add(3, 4);
        System.out.println("add = " + add);
    }
}
